package cqrtplm.aop;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.hustcad.plm.pdm.partbom.dto.PartBomTree;
import com.hustcad.plm.pdm.partbom.dto.SavePartAttrsDTO;
import com.hustcad.plm.pdm.partbom.dto.SavePartBomAttrsDTO;
import com.hustcad.plm.pdm.partbom.service.TyplmPartService;
import com.hustcad.plm.pdm.partbom.vo.PartBomTreeByFilterVO;
import com.ty.basic.constant.TableTypeConstrant;
import com.ty.basic.dto.constraint.IbaDTO;
import com.ty.basic.entity.part.PartDO;
import com.ty.basic.entity.part.PartMasterDO;
import cqrtplm.common.CommonService;
import cqrtplm.constant.RTErrorCodeEnum;
import cqrtplm.mapper.RTChangeMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Aspect
@Component
@Slf4j
@Order(Ordered.LOWEST_PRECEDENCE)
public class PartBomModifyAOP {
    @Resource
    private TyplmPartService typlmPartService;
    @Resource
    private RTChangeMapper rtChangeMapper;

    @Resource
    private CommonService commonService;
    /**
     * 修改BOM时，检查是否有编码相同且段号相同的的子件
     */
    @Before(value = "execution(* com.hustcad.plm.pdm.partbom.service.TyplmPartBomService.batchSavePartBomAttrs(..))")
    public void partBomModifyVerifyAop(JoinPoint point) throws Throwable {
        StringBuffer msg=new StringBuffer();
        List<String> statusList = new ArrayList<>();
        Object[] args = point.getArgs();
        if (ObjectUtil.isNotEmpty(args[0])) {
            SavePartBomAttrsDTO savePartBomAttrsDTO = (SavePartBomAttrsDTO) args[0];
            List<SavePartAttrsDTO> savePartAttrsDTOList = savePartBomAttrsDTO.getSavePartAttrsDTOList();
            if (CollUtil.isNotEmpty(savePartAttrsDTOList)) {
                //根据parentOid去重
                List<SavePartAttrsDTO> uniqueList = savePartAttrsDTOList.stream()
                        .collect(Collectors.toMap(
                                SavePartAttrsDTO::getParentPartOid, // 使用oid作为key
                                dto -> dto, // 使用dto本身作为value
                                (existing, replacement) -> existing // 如果key重复，保留第一个遇到的元素
                        )).values().stream().collect(Collectors.toList());
                //根据parentOid获取子件
                Map<BigInteger, List<PartBomTree>> parentPartOidMap = new HashMap<>();
                for (SavePartAttrsDTO savePartAttrsDTO : uniqueList) {
                    BigInteger parentPartOid = savePartAttrsDTO.getParentPartOid();
                    PartDO partDO = this.typlmPartService.queryPartByOid(parentPartOid,TableTypeConstrant.TY_PART_OTYPE);
                    PartBomTreeByFilterVO bomTreeByFilterVO = this.commonService.queryChildParts(partDO.getPartnumber(), partDO.getOid().toString(), "Design", Boolean.FALSE, null, "1", Boolean.FALSE);
                    List<PartBomTree> list = bomTreeByFilterVO.getPartBomTreeList();
                    parentPartOidMap.put(parentPartOid, list);
                }
                StringBuffer statusMsg=null;
                for (SavePartAttrsDTO savePartAttrsDTO : savePartAttrsDTOList) {
                    StringBuffer sb=new StringBuffer();
                    BigInteger partOid = savePartAttrsDTO.getOid();
                    BigInteger parentPartOid =savePartAttrsDTO.getParentPartOid();
                    BigInteger masterOid = savePartAttrsDTO.getMasterOid();
                    PartMasterDO partMasterDO= typlmPartService.queryPartMasterDOByOID(masterOid);
                    BigInteger refoid = savePartAttrsDTO.getRefoid();
                    PartDO partDO = this.typlmPartService.queryPartByOid(partOid,TableTypeConstrant.TY_PART_OTYPE);
                    String status=partDO.getLifecyclestagekey();
                    if (!"RELEASED".equals(status)){
                        statusMsg=new StringBuffer();
                        statusMsg.append(partDO.getPartnumber()).append("(").append(partDO.getName()).append(")");
                        statusList.add(statusMsg.toString());
                    }
                    List<PartBomTree> childList = parentPartOidMap.get(parentPartOid);
                    List<PartBomTree> chilldList2=childList.stream().filter(item -> new BigInteger(item.getMasteredoid()).equals(masterOid) && !item.getRefoid().equals(refoid)).collect(Collectors.toList());
                    if (CollUtil.isEmpty(chilldList2)){
                        continue;
                    }
                    String SegmNum = "";
                    List<IbaDTO> linkIbaAttrs = savePartAttrsDTO.getLinkIbaAttrs();
                    if (CollUtil.isNotEmpty(linkIbaAttrs)) {
                        for (IbaDTO ibaDTO : linkIbaAttrs) {
                            String key=ibaDTO.getKey();
                            String value = ibaDTO.getValue();
                            if ("SegmNum".equals(key)){
                                SegmNum=value;
                            }
                        }
                    }
                    if (StringUtils.isNotBlank(SegmNum)) {
                        for (PartBomTree partBomTree : chilldList2){
                            BigInteger usageLinkOid = partBomTree.getOid();
                            String usageLinkOtype = partBomTree.getOtype();
                            String numberPath =partBomTree.getNumberPath();
                            String[] numberPaths = numberPath.split("\\/");
                            String segmNum =rtChangeMapper.queryIBAValueByOidAndOtype(String.valueOf(usageLinkOid), usageLinkOtype, "SegmNum");
                            if (SegmNum.equals(segmNum)) {
                                if (!sb.toString().contains(partMasterDO.getPartnumber())){
                                    sb.append(partMasterDO.getPartnumber()).append("__"+segmNum).append(",");
                                }
                            }
                        }
                    }
                    if (StringUtils.isNotBlank(sb.toString())) {
                        sb.deleteCharAt(sb.length()-1);
                        msg.append(partDO.getObjnumber()+"下的"+sb.toString()).append(";");
                    }
                }
            }
        }
        if (CollUtil.isNotEmpty(statusList)) {
            throw RTErrorCodeEnum.CUSTOM_EXCEPTION.getException("提示："+String.join(",", statusList)+"的状态未生效，不允许搭建到BOM中！");
        }
        if (StringUtils.isNotBlank(msg.toString())) {
            msg.deleteCharAt(msg.length()-1);
            throw RTErrorCodeEnum.CUSTOM_EXCEPTION.getException("提示："+msg.toString()+"段号重复，请检查！");
        }
    }
}